package com.plian.system.service.fr.enterprise.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.entity.fr.enterprise.Enterprise;
import com.plian.system.entity.fr.enterprise.EnterprisePlate;
import com.plian.system.entity.sys.FormHistoryRecord;
import com.plian.system.mapper.fr.enterprise.EnterpriseMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.page.Page;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.fr.enterprise.IEnterprisePlateService;
import com.plian.system.service.fr.enterprise.IEnterpriseService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.system.IFormHistoryRecordService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.fr.enterprise.EnterpriseVO;
import com.plian.system.wrapper.fr.enterprise.EnterpriseWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;
import static com.plian.system.constant.sys.FormTypeConstant.FR_ENTERPRISE;

/**
 * @Description: TODO
 * @Author: Take-off
 * @Date: 2023/4/11 2:29 PM
 * @Param
 * @return
 * @Version: 1.0
 **/
@Slf4j
@Service
@AllArgsConstructor
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements IEnterpriseService, BaseFlowService {

    private final EnterpriseWrapper enterpriseWrapper;

    private final EnterpriseMapper enterpriseMapper;

    private final FormWorkflowService formWorkflowService;

    private final IFormCodeService formCodeService;

    private final IFormHistoryRecordService formHistoryRecordService;

    private final IEnterprisePlateService enterprisePlateService;

    @Override
    public boolean saveOrUpdate(Enterprise enterprise) {
        if (! Optional.ofNullable(enterprise.getId()).isPresent()) {
            enterprise.setId(UuidUtil.get32UUID());
            enterprise.setUpdateTime(new Date());
            enterprise.setOrgId(TokenUtil.getTokenOrgId());
            enterprise.setFormType( String.valueOf(FormTypeConstant.FR_ENTERPRISE));
            enterprise.setCode( formCodeService.getCode(FormTypeConstant.FR_ENTERPRISE));
        }
        return super.saveOrUpdate(enterprise);
    }

    @Override
    public boolean submit(Enterprise enterprise){
        String id = enterprise.getId();
        if (Optional.ofNullable(id).isPresent()){
            //edit
            Enterprise oldEnterprise = getById(id);
            if (!enterprise.equals(oldEnterprise)){
                try {
                    ObjectMapper mapper=new ObjectMapper();
                    EnterpriseVO enterpriseVO =enterpriseWrapper.entityToVO(oldEnterprise);
                    formHistoryRecordService.submit(FormHistoryRecord.builder().formType(String.valueOf(FormTypeConstant.FR_ENTERPRISE))
                            .record(mapper.writeValueAsString(enterpriseVO)).recordId(id).build());
                } catch (Exception e) {
                    log.error("企业信息--> 历史数据版本保存失败");
                }

            }
            enterprise.setUpdateTime(new Date());
            enterprise.setInitialId(id);
            enterprise.setOrgId(TokenUtil.getTokenOrgId());
        }
        boolean result = saveOrUpdate(enterprise);
        if (result){
            //保存子节点
            List<EnterprisePlate> enterprisePlates = enterprise.getEnterprisePlates();
            if (CollectionUtil.isNotEmpty(enterprisePlates)){
                for (EnterprisePlate enterprisePlate : enterprisePlates){
                    if (enterprisePlate.getId() != null &&
                            Optional.ofNullable(enterprisePlate.getIsDeleted()).isPresent() && enterprisePlate.getIsDeleted().intValue() == 1) {
                        enterprisePlateService.removeById(enterprisePlate.getId());
                    }else {
                        enterprisePlate.setBaseId(enterprise.getId());
                        enterprisePlateService.saveOrUpdate(enterprisePlate);
                    }
                }
            }

        }
        return result;
    }

    @Override
    public boolean deleteLogic(List<Long> ids) {
        boolean result = false;
        if (CollectionUtil.isNotEmpty(ids)){
            List<Enterprise> enterprises = listByIds(ids);
            enterprises.forEach( enterprise -> {
                enterprise.setIsDeleted("1");
            });
             result = updateBatchById(enterprises);
            enterprisePlateService.deleteByParentId(ids);
        }
        return result;
    }

    @Override
    public ListResult<EnterpriseVO> list( Query query) {
        List<SearchEntity> entityList = query.getSearch();
        QueryWrapper<Enterprise> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new Enterprise()), entityList
        );
        if (!Optional.ofNullable(query.getFlag()).isPresent() || query.getFlag() != 1) {
            queryWrapper.eq("org_id", TokenUtil.getTokenOrgId());
        }
        IPage<Enterprise> pages = page(Condition.getPage(query), queryWrapper);
        List<EnterpriseVO> enterpriseVOS = enterpriseWrapper.entityToVO(pages.getRecords());
        ListResult<EnterpriseVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(enterpriseVOS);
        listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
        return listResult;
    }

    @Override
    public EnterpriseVO getDetailObj(Enterprise enterprise){
        Enterprise detail = getOne(Condition.getQueryWrapper(enterprise));
        EnterpriseVO enterpriseVO = enterpriseWrapper.entityToVO(detail);
        List<EnterprisePlate> enterprisePlates = enterprisePlateService.list(new LambdaQueryWrapper<EnterprisePlate>().eq(EnterprisePlate::getBaseId, enterpriseVO.getId()));
        enterpriseVO.setEnterprisePlates(enterprisePlates);
        return enterpriseVO;
    }

    @Override
    public EnterpriseVO findByOrgId(String orgId){
        EnterpriseVO enterpriseVO = new EnterpriseVO();
        List<Enterprise> enterprises = list(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getOrgId, orgId));
        if (CollectionUtil.isNotEmpty(enterprises)){
            Enterprise enterprise = enterprises.get(0);
            enterpriseVO = enterpriseWrapper.entityToVO(enterprise);
        }
        return enterpriseVO;
    }

    @Override
    public HashMap<String,Object> commit(String id) {
        handleStatus(id, FormStatusConstant.FLOW);
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String,Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(id, FormStatusConstant.FINISH);
    }

    @Override
    public Boolean reject(String id, int formState,String comment) {
        return handleStatus(id, formState);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(formId, UNREVIEWED);
    }

    private Boolean handleStatus(String id, int updateStatus) {
        try {
            Enterprise enterprise = getById(id);
            enterprise.setStatus(String.valueOf(updateStatus));
            updateById(enterprise);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        LambdaQueryWrapper<Enterprise> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Enterprise::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
        List<Enterprise> enterprises = list(queryWrapper);
        List<EnterpriseVO> enterpriseVOS = enterpriseWrapper.entityToVO(enterprises);
        List<PageData> pageDataList = new ArrayList<>();
        try{
            if (CollectionUtil.isNotEmpty(enterpriseVOS)){
                for (EnterpriseVO vo : enterpriseVOS){
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getOrgName());
                    pd.put("APPLICANTNAME","");
                    pd.put("applicantId", "");
                    pd.put("applyOrganizationId", vo.getOrgId());
                    pd.put("formType", vo.getFormType());
                    pd.put("orgName", vo.getOrgName());
                    pageDataList.add(pd);
                }
            }
            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FR_ENTERPRISE);
    }

    @Override
    public EnterpriseVO getEnterpriseVO(Object id) {
        return enterpriseWrapper.entityToVO(getById(Long.valueOf(String.valueOf(id))));
    }

    @Override
    public ListResult reportList(PageData pd){
        Page page=new Page(false,pd);
        page.setPd(pd);
        List<PageData> l = enterpriseMapper.reportList(page);
        ListResult listResult= new ListResult(CommonCode.SUCCESS,page.getTotal());
        listResult.setList(l);
        return listResult;
    }

    @Override
    public List<Enterprise> getAllUnitCheckName(){
        return list(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getIsDeleted,"0")
                .isNotNull(Enterprise::getUnitCheck).ne(Enterprise::getUnitCheck,"无"));
    }

    @Override
    public List<Enterprise> findByOrgIds(List<String> orgIds){
        return list(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getIsDeleted,"0")
                .in(Enterprise::getOrgId,orgIds));
    }

    @Override
    public Enterprise findByOrg(String orgId){
        return getOne(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getIsDeleted,"0")
                .eq(Enterprise::getOrgId,orgId));
    }

    @Override
    public List<PageData> selectDistinct(PageData pageData){
        return enterpriseMapper.selectDistinct(pageData);
    }
}
